home *** CD-ROM | disk | FTP | other *** search
/ ftp.mactech.com 2010 / ftp.mactech.com.tar / ftp.mactech.com / machack / Hacks96 / BetterADsecurity.sit / Better AD security / Source / ExtensionShell.c < prev    next >
C/C++ Source or Header  |  1996-06-21  |  15KB  |  659 lines

  1. /*    NAME:
  2.         ExtensionShell.c
  3.  
  4.     WRITTEN BY:
  5.         Dair Grant, dair@kagi.com
  6.                 
  7.     DESCRIPTION:
  8.         This file contains the main entry point of Extension Shell. It 
  9.         calls everything else to do the actual work.        
  10.  
  11.     NOTES:
  12.         We don't lock our code resource down by hand, so we depend on
  13.         having the System Heap and Locked attributes set.
  14.  
  15.     RELEASE INFORMATION:
  16.         Extension Shell is freeware, and Copyright © 1993-96 Dair Grant.
  17.  
  18.         You may not charge for Extension Shell itself, or redistribute
  19.         it as part of a commercial package without my prior permission.
  20.  
  21.         If you use Extension Shell in a commercial Extension, you are
  22.         obliged to display some form of indication that your product
  23.         uses Extension Shell. This notice must be plainly visible to
  24.         users (either in the 'vers' resource, or in some other form of
  25.         documentation), and not just those curious enough to use ResEdit.
  26.         
  27.         Shareware and Freeware products can use the code without notice.
  28.  
  29.     ___________________________________________________________________________
  30. */
  31. //=============================================================================
  32. //        Include files
  33. //-----------------------------------------------------------------------------
  34. #include <MixedMode.h>
  35. #include <Resources.h>
  36. #include <Gestalt.h>
  37. #include "A4Stuff.h"
  38. #include "SetupA4.h"
  39. #include "ES.h"
  40. #include "ES Address Table.h"
  41. #include "ExtensionShell.h"
  42. #include "InstallCode.h"
  43. #include "UninstallCode.h"
  44. #include "ShowIcon.h"
  45. #include "NotifyMsg.h"
  46.  
  47.  
  48.  
  49.  
  50.  
  51.  
  52.  
  53.  
  54.  
  55.  
  56.  
  57.  
  58.  
  59.  
  60.  
  61. //=============================================================================
  62. //        Private function prototypes
  63. //-----------------------------------------------------------------------------
  64. void            main(void);
  65. void            InitToolbox(void);
  66. void            InitParamBlock(void);
  67. void            CallESHandler(short theMsg);
  68. OSErr            DoInstall(void);
  69. void            DoUninstall(void);
  70. void            DoErrors(void);
  71. void            DoIcons(void);
  72. pascal Boolean    IsKeyMouseDown(short keyCode, Boolean checkMouse);
  73. pascal Boolean    IsTrapAvailable(short trapWord);
  74. pascal Boolean    IsPowerMac(void);
  75. pascal Boolean    IsTrapNative(short trapWord);
  76.  
  77.  
  78.  
  79.  
  80.  
  81.  
  82.  
  83.  
  84.  
  85.  
  86.  
  87.  
  88.  
  89.  
  90.  
  91. //=============================================================================
  92. //        Global variables
  93. //-----------------------------------------------------------------------------
  94. FakeQD            gTheQDGlobals;
  95. ESParamBlock    gTheParamBlock;
  96. ESAddressTable    *gTheESAddressTable;
  97.  
  98.  
  99.  
  100.  
  101.  
  102.  
  103.  
  104.  
  105.  
  106.  
  107.  
  108.  
  109.  
  110.  
  111.  
  112. //=============================================================================
  113. //        main : Entry point to our 'INIT' code resource.
  114. //-----------------------------------------------------------------------------
  115. //        Note :    We need to set up A4 so that we can access our globals. We
  116. //                do this using the standard Metrowerks routines.
  117. //
  118. //                We don't lock ourself down in memory, or call DetachResource
  119. //                on ourselves. We assume that the 'INIT' resource was compiled
  120. //                with the System Heap and Locked attributes set.
  121. //-----------------------------------------------------------------------------
  122. void main(void)
  123. {    long            oldA4;
  124.     THz                oldZone;
  125.  
  126.  
  127.  
  128.  
  129.     // Set up A4 and switch to the System Zone
  130. #ifndef powerc
  131.     oldA4 = SetCurrentA4();
  132. #endif
  133.     oldZone = GetZone();
  134.     SetZone(SystemZone());
  135.  
  136.  
  137.  
  138.     // Initialise Extension Shell and the ES Handler
  139.     InitToolbox();
  140.     InitParamBlock();
  141.     CallESHandler(kInitialiseParamBlock);
  142.  
  143.  
  144.  
  145.     // Install everything the ES Handler requested
  146.     if (DoInstall() != noErr)
  147.         {
  148.         // If there's a problem, let the handler know
  149.         CallESHandler(kHandleError);
  150.         
  151.         
  152.         // If we're allowed to, try and clean up after ourselves
  153.         if (gTheParamBlock.removeInstalledCode)
  154.             DoUninstall();
  155.         }
  156.  
  157.  
  158.     // If the ES Handler has registered an error, handle it
  159.     if (gTheParamBlock.beepNow || gTheParamBlock.postError)
  160.         DoErrors();
  161.         
  162.     
  163.     // Show any icons which are to be shown
  164.     DoIcons();
  165.  
  166.  
  167.     // Restore the heap zone and A4
  168.     SetZone(oldZone);
  169. #ifndef powerc
  170.     SetA4(oldA4);
  171. #endif
  172. }
  173.  
  174.  
  175.  
  176.  
  177.  
  178.  
  179.  
  180.  
  181.  
  182.  
  183.  
  184.  
  185.  
  186.  
  187.  
  188. //=============================================================================
  189. //        InitToolbox : Initialises the Toolbox.                                                                 
  190. //-----------------------------------------------------------------------------
  191. //        Note :    If we initialise all the Toolbox Managers, we will erase the
  192. //                screen. This looks ugly - so don't define __InitAllToolbox__
  193. //                unless you really don't care.
  194. //-----------------------------------------------------------------------------
  195. void InitToolbox(void)
  196. {
  197.  
  198.  
  199.  
  200.     // Initialise the bits of the Toolbox that we need
  201.     InitGraf(&gTheQDGlobals.thePort);
  202.  
  203.  
  204. #ifdef __InitAllToolbox__
  205.     // This fixes the pre-Mac II bug that can happen if we try
  206.     // and create a window from within an INIT.
  207.     *((void**)DragHook) = nil;
  208.     *((void**)DeskHook) = nil;
  209.  
  210.  
  211.     // Initialise the rest of the Toolbox
  212.     InitFonts();
  213.     InitWindows();
  214.     InitCursor();
  215.     InitMenus();
  216.     InitDialogs(nil);
  217.     TEInit();
  218. #endif
  219.     
  220.     
  221.     // Flush out any events that may be lurking
  222.     FlushEvents(everyEvent, 0);
  223.     FlushEvents(everyEvent, 0);
  224.     FlushEvents(everyEvent, 0);
  225. }
  226.  
  227.  
  228.  
  229.  
  230.  
  231.  
  232.  
  233.  
  234.  
  235.  
  236.  
  237.  
  238.  
  239.  
  240.  
  241. //=============================================================================
  242. //        InitParamBlock : Initialise gTheParamBlock.                                                             
  243. //-----------------------------------------------------------------------------
  244. //        Note :    We want to minimise the work the ES Handler has to do, so
  245. //                we initialise the fields to their most 'normal' values.
  246. //-----------------------------------------------------------------------------
  247. void InitParamBlock(void)
  248. {    OSErr        myErr;
  249.  
  250.     
  251.  
  252.     
  253.     // Initialise the general values
  254.     myErr = Gestalt(gestaltSystemVersion, &gTheParamBlock.systemVersion);
  255.     gTheParamBlock.NotificationMsg    = NotificationMessage;
  256.     gTheParamBlock.IsKeyMouseDown    = IsKeyMouseDown;
  257.     gTheParamBlock.IsTrapAvailable    = IsTrapAvailable;
  258.     gTheParamBlock.IsPowerMac        = IsPowerMac;
  259.     gTheParamBlock.IsTrapNative        = IsTrapNative;
  260.  
  261.  
  262.     // Initialise the Icon related values
  263.     gTheParamBlock.numIcons                = 0;
  264.     gTheParamBlock.animationDelay        = 3;
  265.     
  266.         
  267.     // Initialise the installable code related values
  268.     gTheParamBlock.installAddressTable    = false;
  269.     gTheParamBlock.numCodeResources        = 0;
  270.     gTheParamBlock.errorIndex            = 0;
  271.     gTheParamBlock.theErr                = noErr;
  272.  
  273.         
  274.     // Initialise the error handling related values
  275.     gTheParamBlock.removeInstalledCode    = false;
  276.     gTheParamBlock.beepNow                = false;
  277.     gTheParamBlock.postError            = false;
  278.     gTheParamBlock.errorStringsID        = 0;
  279.     gTheParamBlock.errorStringIndex        = 0;
  280. }
  281.  
  282.  
  283.  
  284.  
  285.  
  286.  
  287.  
  288.  
  289.  
  290.  
  291.  
  292.  
  293.  
  294.  
  295.  
  296. //=============================================================================
  297. //        CallESHandler : Execute the ES Handler CODE resource.                                                             
  298. //-----------------------------------------------------------------------------
  299. //        Note :    This routine can be called several times. We load the CODE
  300. //                resource in once, and save it in a static variable. When
  301. //                the System closes our resource fork, the code will get
  302. //                flushed out (we're not calling DetachResource).
  303. //
  304. //                If we can't find the ES Handler, we drop into the Debugger.
  305. //-----------------------------------------------------------------------------
  306. void CallESHandler(short theMsg)
  307. {    static ESHandlerProc    theHandler = (ESHandlerProc) nil;
  308.     Handle                    theHnd;
  309.  
  310.  
  311.  
  312.     // If we've not already loaded the code, do so, and lock it down
  313.     if (theHandler == nil)
  314.         {
  315.         theHnd = Get1Resource(kESHandlerCodeType, kESHandlerCodeID);
  316.         if (theHnd == nil)
  317.             DebugStr("\pExtension Shell - couldn't find ES Handler");
  318.         else
  319.             HLock(theHnd);
  320.             
  321.         theHandler = (ESHandlerProc) StripAddress(*theHnd);
  322.         }
  323.     
  324.  
  325.     // Call the code with the message and the param block
  326.     (*theHandler)(theMsg, &gTheParamBlock);
  327. }
  328.  
  329.  
  330.  
  331.  
  332.  
  333.  
  334.  
  335.  
  336.  
  337.  
  338.  
  339.  
  340.  
  341.  
  342.  
  343. //=============================================================================
  344. //        DoInstall : Install what the ES Handler wants installed.                                                             
  345. //-----------------------------------------------------------------------------
  346. //        Note :    This routine attempts to install the routines the ES Handler
  347. //                has requested. If there is a problem, the appropriate fields
  348. //                in gTheParamBlock will be filled in, and an error code
  349. //                returned.
  350. //-----------------------------------------------------------------------------
  351. OSErr DoInstall(void)
  352. {    short    i;
  353.     OSErr    theErr = noErr;
  354.  
  355.  
  356.  
  357.     // Install the address table, if one has been requested. This has to
  358.     // be done first in case installed code is going to be called before
  359.     // we're finished (e.g., a trap patch to GetResource).
  360.     //
  361.     // If the address table is installed correctly, we call the ES
  362.     // Handler to give it a chance to initialise any fields it may
  363.     // have added. If it sets gTheParamBlock.theErr to anything other
  364.     // than noErr, we abort the installation process.
  365.     if (gTheParamBlock.installAddressTable)
  366.         {
  367.         InstallESAddressTable();
  368.         
  369.         CallESHandler(kInitialiseAddrsTable);
  370.         if (gTheParamBlock.theErr != noErr)
  371.             return(gTheParamBlock.theErr);
  372.         }
  373.  
  374.  
  375.     // Install each resource in turn. If there's a problem, we save the
  376.     // error details and break out of the loop.
  377.     if (gTheParamBlock.numCodeResources >= 1)
  378.         {
  379.         for (i = 1; i <= gTheParamBlock.numCodeResources && theErr == noErr; i++)
  380.             {
  381.             theErr = InstallCode(i);
  382.             if (theErr != noErr)
  383.                 {
  384.                 gTheParamBlock.errorIndex = i;
  385.                 gTheParamBlock.theErr     = theErr;
  386.                 }
  387.             }
  388.         }
  389.         
  390.             
  391.     // Return any error code
  392.     return(gTheParamBlock.theErr);
  393. }
  394.  
  395.  
  396.  
  397.  
  398.  
  399.  
  400.  
  401.  
  402.  
  403.  
  404.  
  405.  
  406.  
  407.  
  408.  
  409. //=============================================================================
  410. //        DoUninstall : Try and uninstall anything which has been installed.
  411. //-----------------------------------------------------------------------------
  412. //        Note :    This routine attempts to remove the routines the ES Handler
  413. //                resource tried to install. The error index is assumed to
  414. //                indicate which resource could not be installed, and so
  415. //                only entries before this index are candidates for removal.
  416.  
  417. //                We make *no* guarantees as to what can be removed. Hopefully,
  418. //                most things can, but you never know.
  419. //-----------------------------------------------------------------------------
  420. void DoUninstall(void)
  421. {    short    i;
  422.  
  423.  
  424.  
  425.     // gTheParamBlock.ErrorIndex contains the index of the item that
  426.     // couldn't be installed. We try and uninstall everything before this.
  427.     if (gTheParamBlock.errorIndex > 1 && gTheParamBlock.numCodeResources >= 1)
  428.         {
  429.         for (i = 1; i < gTheParamBlock.errorIndex; i++)
  430.             UninstallCode(i);
  431.         }
  432. }
  433.  
  434.  
  435.  
  436.  
  437.  
  438.  
  439.  
  440.  
  441.  
  442.  
  443.  
  444.  
  445.  
  446.  
  447.  
  448. //=============================================================================
  449. //        DoErrors : Provide some error handling capabilities.                                                                 
  450. //-----------------------------------------------------------------------------
  451. //        Note :    This routine is how Extension Shell communicates errors to the
  452. //                user. The two functions it offers are to beep, and to post a 
  453. //                Notification Manager dialog to the user.
  454. //-----------------------------------------------------------------------------
  455. void DoErrors(void)
  456. {
  457.  
  458.  
  459.     // If we're to beep, do so now
  460.     if (gTheParamBlock.beepNow)
  461.         SysBeep(30);
  462.     
  463.         
  464.     // If we're to post a NM message, do so
  465.     if (gTheParamBlock.postError)
  466.         NotificationMessage(gTheParamBlock.errorStringsID, gTheParamBlock.errorStringIndex);
  467. }
  468.  
  469.  
  470.  
  471.  
  472.  
  473.  
  474.  
  475.  
  476.  
  477.  
  478.  
  479.  
  480.  
  481.  
  482.  
  483. //=============================================================================
  484. //        DoIcons : Call PlotINITIcon to display the icons.                                                             
  485. //-----------------------------------------------------------------------------
  486. //        Note :    We pull the values out of gTheParamBlock, and let PlotINITIcon
  487. //                do all the work.
  488. //-----------------------------------------------------------------------------
  489. void DoIcons(void)
  490. {    Boolean        useIconSuite;
  491.  
  492.  
  493.  
  494.  
  495.     // Call PlotINITIcon to do the work
  496.     useIconSuite = IsTrapAvailable(_OpenCPort) && IsTrapAvailable(_IconDispatch);
  497.     PlotINITIcon(useIconSuite,
  498.                  gTheParamBlock.animationDelay,
  499.                  gTheParamBlock.numIcons,
  500.                  &gTheParamBlock.theIcons);
  501. }
  502.  
  503.  
  504.  
  505.  
  506.  
  507.  
  508.  
  509.  
  510.  
  511.  
  512.  
  513.  
  514.  
  515.  
  516.  
  517. //=============================================================================
  518. //        IsKeyMouseDown : Called by the ES Handler to scan the keyboard.
  519. //-----------------------------------------------------------------------------
  520. //        Note :    We return true if the key corresponding to KeyCode is pressed,
  521. //                and false otherwise.
  522. //
  523. //                If checkMouse is true, we also return false if the mouse is not
  524. //                pressed, and true if it is.
  525. //-----------------------------------------------------------------------------
  526. pascal Boolean IsKeyMouseDown(short keyCode, Boolean checkMouse)
  527. {    unsigned char    theKeys[16];
  528.  
  529.  
  530.  
  531.  
  532.     // First check the keyboard
  533.     GetKeys((void *) theKeys);
  534.     if ((theKeys[keyCode >> 3] >> (keyCode & 7)) & 1)
  535.         return(true);
  536.     
  537.     
  538.     // Then check the mouse, if we're allowed to
  539.     if (checkMouse)
  540.         return(Button());
  541.     
  542.     
  543.     // If we've got this far, nothing is being pressed
  544.     return(false);
  545. }
  546.  
  547.  
  548.  
  549.  
  550.  
  551.  
  552.  
  553.  
  554.  
  555.  
  556.  
  557.  
  558.  
  559.  
  560.  
  561. //=============================================================================
  562. //        IsTrapAvailable : Determines if a given trap number is implemented.                                                             
  563. //-----------------------------------------------------------------------------
  564. pascal Boolean IsTrapAvailable(short trapWord)
  565. {    TrapType    trapType;
  566.     short        numToolboxTraps;
  567.  
  568.  
  569.  
  570.     // Check trap word for Toolbox bit
  571.     trapType = (trapWord & 0x0800) ? ToolTrap : OSTrap;
  572.     
  573.     
  574.     // If it's a Toolbox trap...
  575.     if (trapType == ToolTrap)
  576.         {
  577.         // Mask through largest # of traps available
  578.         trapWord &= 0x07FF;
  579.         
  580.         
  581.         // Is _InitGraf at the same address as 0xAA6E?
  582.         if (NGetTrapAddress(kInitGrafTrap,ToolTrap) == NGetTrapAddress(0xAA6E, ToolTrap))
  583.             numToolboxTraps = 0x0200;                // Yes, only this many entries in dispatch table
  584.         else
  585.             numToolboxTraps = 0x0400;                // No, dispatch table is larger
  586.         
  587.         
  588.         // Trap # bigger than dispatch table? If so it's a bogus trap, so abort
  589.         if (trapWord > numToolboxTraps)
  590.             return(false);
  591.         } 
  592.  
  593.  
  594.  
  595.     // Return trap address if it's not an unimplemented trap
  596.     return(NGetTrapAddress(trapWord, trapType) != NGetTrapAddress(kUnimplementedTrap, ToolTrap));
  597. }
  598.  
  599.  
  600.  
  601.  
  602.  
  603.  
  604.  
  605.  
  606.  
  607.  
  608.  
  609.  
  610.  
  611.  
  612.  
  613. //=============================================================================
  614. //        IsPowerMac : Is this a PowerMac?
  615. //-----------------------------------------------------------------------------
  616. pascal Boolean IsPowerMac(void)
  617. {    long        result;
  618.     OSErr        theErr;
  619.     
  620.     
  621.     theErr = Gestalt(gestaltSysArchitecture, &result);
  622.     if (theErr == noErr && result == gestaltPowerPC)
  623.         return(true);
  624.     else
  625.         return(false);
  626. }
  627.  
  628.  
  629.  
  630.  
  631.  
  632.  
  633.  
  634.  
  635.  
  636.  
  637.  
  638.  
  639.  
  640.  
  641.  
  642. //=============================================================================
  643. //        IsTrapNative : Is a trap native?
  644. //-----------------------------------------------------------------------------
  645. pascal Boolean IsTrapNative(short trapWord)
  646. {    TrapType            trapType;
  647.     short                *theCode;
  648.  
  649.  
  650.  
  651.     // Get the address of the trap code
  652.     trapType = (trapWord & 0x0800) ? ToolTrap : OSTrap;
  653.     theCode = (short *) NGetTrapAddress(trapWord, trapType);
  654.     
  655.     
  656.     // If the trap is native, it will start with the Mixed Mode Magic word
  657.     return(*theCode == _MixedModeMagic);
  658. }
  659.